#define _CRT_SECURE_NO_WARNINGS 1
#include"address_book.h"


//-----这个函数是检查申请的空间是否足够，如果不够将进行扩容
void CheckCapacity(struct contact* con) {
	if (con->size == con->capacity) {
		con->data = (struct personal_information*)realloc(con->data, sizeof(struct personal_information) * (con->capacity) * 2);
		if (con->data == NULL) {
			printf("扩容失败:%s", strerror(errno));
		}
	}
}




//-----这个函数是将之前存储在文件中个人信息再次存储在创建的动态数组中    
void LoadContact(struct contact* con) {
	int i = 0;
	FILE* file = fopen("contact.txt", "rb");
	if (file == NULL) {
		printf("LoadContact:%s\n", strerror(errno));//如果文件没有打开就是不存在或者其他原因
		return;
	}

	//假如存在就执行下面的程序
	while (fread(&con->data[con->size], sizeof(struct personal_information), 1, file)) {
		(con->size)++;
		CheckCapacity(con);
	}
	fclose(file);
}




//-----这个函数是用来初始化创建的通讯录的
void Initialize(struct contact* con) {
	con->data = (struct personal_information*)malloc(sizeof(struct personal_information) * 3);//最开始的存储的大小就是3个联系人的大小
	if ((con->data) == NULL){
		printf("初始化失败\n");
		return;
	}

	con->capacity = 3;   //第一次初始化的默认大小
	con->size = 0;//没有进行存储的情况下就是0个人        size就是已经存储的联系人

	LoadContact(con);//在初始化之后，如果之前文件中有之前存储的联系人就将之前的联系读取进入这个动态开辟的空间
}







//-----1.添加联系人
void AddContact(struct contact* con) {
	CheckCapacity(con);//添加联系人之前也需要检查容量是否充足

	printf("请输入名字:");
	scanf("%s", con->data[con->size].name);

	printf("请输入性别:");
	scanf("%s", con->data[con->size].sex);


	printf("请输入电话:");
	scanf("%s", con->data[con->size].telephone);

	printf("请输入地址:");
	scanf("%s", con->data[con->size].address);

	(con->size)++;//全部添加完成之后需要全部进行+1
	printf("添加完成\n");
}













//-----删除联系人用到的查找函数
int FindName(struct contact* con,char* name) {//这个函数在找到指定的联系人之后，会返回这个联系人的下标
	int i = 0;
	for (i = 0; i < con->size; i++) {
		if (strcmp(name, con->data[i].name)==0) {
			return i;
		}
	}
	return-1;//所有的字符串都比对失败的情况下就返回-1
}









//-----2.删除指定联系人
void  DeleteContact(struct contact* con) {
	char name[NAME];
	printf("请输入删除的联系人的名字:");
	scanf("%s", name);

	int position = FindName(con,name);//这个函数找到之后会返回名字的下标
	if (position == -1) {
		printf("要删除的人不存在\n");
		return;
	}
	else {//删除了一个，删除的那个后面的联系人都得向前提一位                这里可以使用memove进行替换，但是要算出来需要挪动的总字节数
		for (; position < (con->size-1); position++) {
			con->data[position] = con->data[position + 1];
		}
	}
	con->size--;
}










//-----3.查找指定联系人
void SearchContact(struct contact* con) {
	char name[NAME];
	int position = 0;
	
	printf("请输入查找的人的名字:");
	scanf("%s",name);
	position = FindName(con, name);
	if ( position== -1) {
		printf("查找的人不存在\n");
	}
	else {
		printf("名字:%20s 性别:%-10s 电话:-20%s 地址:-10%s\n",con->data[position].name,con->data[position].sex, con->data[position].telephone, con->data[position].address);
	}
}









//-----4.修改联系人的名字
void ModifyContact(struct contact* con) {
	char name[NAME];
	int position;
	printf("请输入要修改信息的名字:");
	scanf("%s", name);

	position=FindName(con, name);
	if (position == -1) {
		printf("输入的名字不存在\n");
	}
	else {
		printf("请输入名字:");
		scanf("%s", con->data[position].name);

		printf("请输入性别:");
		scanf("%s", con->data[position].sex);


		printf("请输入电话:");
		scanf("%s", con->data[position].telephone);

		printf("请输入地址:");
		scanf("%s", con->data[position].address);

		printf("修改完成\n");
	}
}






//-----5.显示所有的联系人
void ShowContact(struct contact* con) {
	int i = 0;
	for (i = 0; i < con->size; i++) {
		printf("名字:%-20s 性别:%-10s 电话:%-20s 地址:%-10s\n", con->data[i].name, con->data[i].sex,con->data[i].telephone, con->data[i].address);
	}
}







//-----6.清空通讯录
void ClearContact(struct contact* con) {
	FreeUp(con);
	con->data = (struct personal_information*)malloc(sizeof(struct personal_information) * 3);//最开始的存储的大小就是3个联系人的大小
	if ((con->data) == NULL) {
		printf("初始化失败\n");
		return;
	}

	con->capacity = 3;   //第一次初始化的默认大小
	con->size = 0;//没有进行存储的情况下就是0个人        size就是已经存储的联系人
	
	fclose(fopen("contact.txt", "w"));
	printf("清空成功\n");
}







//-----保存通讯录
void SaveContact(struct contact* con) {
	FILE* file = fopen("contact.txt","wb");
	if (file == NULL) {
		printf("存入失败:%s\n",strerror(errno));
	}
	
	for (int i = 0; i < con->size; i++) {
		fwrite(&con->data[i], sizeof(struct personal_information), 1, file);//之所以con->data不行，是因为这个并不是真正的数组，并不是首元素的地址，所以需要精确到具体的元素地址
	}
	fclose(file);
	file = NULL;
}









//-----将申请的空间进行释放
void FreeUp(struct contact* con) {
	free(con->data);
	con->data = NULL;
}


